package com.hyt.it.ogt.ykcj.utils;


import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.hyt.core.constant.CommonConstant;
import com.hyt.it.ogt.ykcj.domain.zs.dto.ImageBaseDTO;
import com.hyt.it.ogt.ykcj.domain.zs.dto.ImageInfoDTO;
import com.hyt.it.ogt.ykcj.domain.zs.dto.TextInfoDTO;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * @program: it-ogt-ykcj
 * @description: 图片模板编辑工具类
 * @author: Yang HuanKun
 * @create: 2022-06-23 15:53
 **/
@Slf4j
public class ImageMarkUtils {

    // url -> file
    final static Cache<String, File> timedCache = CacheUtil.newTimedCache(-1);

    /**
     * 编辑图片,往指定位置添加文字
     *
     * @param list :文字集合
     */
    public static File writeImage(String templatePath, List<ImageBaseDTO> list) {
        FileOutputStream outImgStream = null;
        // 输出图片
        File tempFile = FileUtil.createTempFile(StrUtil.DOT + ImgUtil.IMAGE_TYPE_PNG, Boolean.TRUE);
        tempFile.deleteOnExit();
        try {
            //读取原图片信息
            BufferedImage bufferedImage = ImgUtil.read(getFileByUrl(templatePath));
            Graphics2D g = bufferedImage.createGraphics();

            for (ImageBaseDTO baseDTO : list) {
                if (baseDTO instanceof TextInfoDTO) {
                    TextInfoDTO textInfoDTO = (TextInfoDTO) baseDTO;
                    Assert.notBlank(textInfoDTO.getText(), "缺少渲染的文本");

                    //根据图片的背景设置水印颜色
                    g.setColor(textInfoDTO.getColor());
                    g.setFont(textInfoDTO.getFont());
                    //防锯齿
                    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
                    //设置字体
                    int x = textInfoDTO.getX();
                    //判断是否居中
                    if (textInfoDTO.getIsCenter()) {
                        FontMetrics fm = g.getFontMetrics(textInfoDTO.getFont());
                        // 获得字体在图片中的宽度
                        int fontWidth = fm.stringWidth(textInfoDTO.getText());
                        x = textInfoDTO.getX() - (fontWidth / 2);
                        //画出水印
                        g.drawString(textInfoDTO.getText(), x, textInfoDTO.getY());
                    } else if (textInfoDTO.getWidth() != null && textInfoDTO.getHeight() != null) {
                        FontMetrics fm = g.getFontMetrics(textInfoDTO.getFont());
                        // 获得字体在图片中的宽度
                        int fontMaxWidth = fm.stringWidth(textInfoDTO.getText());
                        // 如果宽度小于最大宽度的话，则进行换行
                        if (textInfoDTO.getWidth() < fontMaxWidth) {
                            StringBuilder lineText = new StringBuilder();
                            int y = textInfoDTO.getY();
                            for (char charText : textInfoDTO.getText().toCharArray()) {
                                String currentLineText = lineText.toString();
                                String currentLineChar = String.valueOf(charText);
                                String concatLineText = StrUtil.concat(Boolean.TRUE, currentLineText, currentLineChar);
                                int currentLineWidth = fm.stringWidth(concatLineText);
                                if (currentLineWidth > textInfoDTO.getWidth()) {
                                    //画出水印
                                    g.drawString(lineText.toString(), x, y);
                                    lineText.setLength(CommonConstant.ZERO);
                                    y += textInfoDTO.getHeight() + CommonConstant.ONE;
                                }
                                lineText.append(charText);
                            }
                            // 画出最后一行文本
                            g.drawString(lineText.toString(), x, y);
                        } else {
                            //画出水印
                            g.drawString(textInfoDTO.getText(), x, textInfoDTO.getY());
                        }
                    } else {
                        //画出水印
                        g.drawString(textInfoDTO.getText(), x, textInfoDTO.getY());
                    }

                } else if (baseDTO instanceof ImageInfoDTO) {
                    ImageInfoDTO imageInfoDTO = (ImageInfoDTO) baseDTO;
                    Assert.notBlank(imageInfoDTO.getUrl(), "缺少渲染的URL");
                    int x = imageInfoDTO.getX();
                    // 是否居中，计算居中的x数值
                    if (imageInfoDTO.getIsCenter()) {
                        x = imageInfoDTO.getX() - (imageInfoDTO.getWidth() / 2);
                    }
                    g.drawImage(ImgUtil.read(getFileByUrl(imageInfoDTO.getUrl())),
                            x,
                            imageInfoDTO.getY(),
                            imageInfoDTO.getWidth(),
                            imageInfoDTO.getHeight(),
                            imageInfoDTO.getColor(),
                            null);
                }
            }
            g.dispose();
            outImgStream = new FileOutputStream(tempFile);
            ImageIO.write(bufferedImage, ImgUtil.IMAGE_TYPE_PNG, outImgStream);
            return tempFile;
        } catch (Exception e) {
            log.error("# 模板证书生成异常", e);
        } finally {
            try {
                if (null != outImgStream) {
                    outImgStream.flush();
                    outImgStream.close();
                }
            } catch (IOException e) {
                log.error("# 证书图片生成IO异常", e);
            }
        }
        return tempFile;
    }

    public static File writePdf(String templatePath, List<ImageBaseDTO> list) {
        File imageFile = writeImage(templatePath, list);
        return PdfManager.imageToPdf(imageFile);
    }

    public static File imgToPdf(File imageFile) {
        return PdfManager.imageToPdf(imageFile);
    }

    /**
     * 通过url获取指定文件
     *
     * @param url
     * @return
     */
    private static File getFileByUrl(String url) {
        File file = timedCache.get(url);
        if (ObjectUtil.isEmpty(file)) {
            String fileType = FileUtil.getSuffix(url);
            File urlTempFile = FileUtil.createTempFile(StrUtil.DOT + fileType, Boolean.TRUE);
            long downloadFileSize = HttpUtil.downloadFile(url, urlTempFile);
            log.debug("# 通过url获取指定文件大小为：{}", downloadFileSize);
            file = urlTempFile;
            timedCache.put(url, urlTempFile);
        }
        return file;
    }
}
